package com.hs.communication.common.protocol;


import com.hs.communication.common.enums.Endian;
import com.hs.communication.common.utils.ByteBuffer;
import com.hs.communication.common.utils.ByteUtil;
import com.hs.communication.common.utils.CrcUtil;

import java.util.Arrays;
import java.util.HashMap;
import java.util.function.Function;

/**
 * 协议工具类
 * 直接读取字节还是字符,字符以什么分隔
 * 比如
 * 字节01 02 03 0A 68读取字节
 * 字符
 * 2200 1000 500,读取字符
 */
public class ProtocolUtil {
    public static String DELIMITER_COMMA = ",";

    public static Endian endian = Endian.SmallEndian;//默认采用小端序
    public static String DELIMITER_SPACE = " ";
    public static String DELIMITER = DELIMITER_SPACE;

    public static final byte RESOLVE_BYTE = 0x00;//按字节解析,也就是说设备传输的是0x10 0x0x 0x68等等这样子的一个个字节
    public static final byte RESOLVE_STR = 0x01;//按字符解析,也就是说设备传输的是类似2200,2200,500类似这样的一个个字符

    public static byte PROTOCOL_RESOLVE = RESOLVE_STR;//协议解析方式


    /**
     * 用于解析数据的map
     * 从串口获取到字节流解析为String
     */
    private static HashMap<Byte, Function<byte[], String>> MAP_RESOLVE = new HashMap<>();

    /**
     * 用于打包封装的map
     * 获取到String封装为byte数组发送到串口
     */
    private static HashMap<Byte, Function<String, byte[]>> MAP_PACK = new HashMap<>();

    static {
        MAP_RESOLVE.put(RESOLVE_BYTE, ByteUtil::bytesToHex);
        MAP_RESOLVE.put(RESOLVE_STR, ByteUtil::bytesToStr);

        MAP_PACK.put(RESOLVE_BYTE, ByteUtil::hexToBytes);
        MAP_PACK.put(RESOLVE_STR, ByteUtil::strToBytes);
    }

    public static String getStr(byte[] bytes) {
        Function<byte[], String> function = MAP_RESOLVE.get(PROTOCOL_RESOLVE);
        return function.apply(bytes);
    }

    public static byte[] getBytes(String str) {
        Function<String, byte[]> function = MAP_PACK.get(PROTOCOL_RESOLVE);
        return function.apply(str);
    }

    /**
     * HashMap<String, Object> map_prop = new HashMap<>();
     * map_prop.put("name", name);
     * map_prop.put("unit", unit);
     * map_prop.put("component", component);
     * map_prop.put("value_property", value_property);
     *
     * @param bytes
     */
    public static void resolveBytes(byte[] bytes) {
        //去除crc,保留数据
        byte[] data = Arrays.copyOfRange(bytes, 0, bytes.length - 2);
        byte[] crc = Arrays.copyOfRange(bytes, bytes.length - 2, bytes.length);

        byte[] crc_calc = CrcUtil.crc16(data);

        if (!CrcUtil.isCrcOk(crc, crc_calc)) {
            System.out.println("crc校验不过");
            return;
        }

//        if (PROTOCOL_RESOLVE == RESOLVE_BYTE) {
            resolveByByte(data);
//        } else if (PROTOCOL_RESOLVE == RESOLVE_STR) {
//            resolveByChar(data);
//        }
    }

    /**
     * 按字符解析(也就是ASC码),如2200,2200,500...
     *
     * @param data
     */
    public static void resolveByChar(byte[] data) {
        String str = new String(data);
        System.out.println("读取的字符串=" + str);
        String[] str_arr = str.split(",");
    }

    /**
     * 按字节解析,如10 68 01 04 06...
     *
     * @param data
     */
    public static void resolveByByte(byte[] data) {
        ByteBuffer buffer = ByteBuffer.wrap(data);
        byte[] prefix = buffer.getBytes(7);//协议头部的7字节,剩下的才是消息内容
    }

    /**
     * y = kx + b
     *
     * @param slope     -> k:    斜率
     * @param intercept -> b 截距
     * @return
     */
    public static int getRandom(int intercept, int slope) {
        return (int) (intercept + Math.floor(Math.random() * slope));
    }

}
